package net.pv.hibernatepokus;

import java.io.Serializable;
import java.math.BigDecimal;
import net.pv.hibernatepokus.domain.Customer;
import net.pv.hibernatepokus.domain.Invoice;
import net.pv.hibernatepokus.domain.Item;
import net.pv.hibernatepokus.domain.Product;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Hello world!
 *
 */
public class App 
{
    
    private static final Logger log = LoggerFactory.getLogger(App.class);
    
    private static final SessionFactory sessionFactory = buildSessionFactory();

    
    public static void main( String[] args ) 
    {
        Transaction tx = getSession().beginTransaction();
        
//        Customer cust = load(Customer.class, 0L);
//        cust.setFirstName("XXY");        
        
        Invoice inv = load(Invoice.class, 0L);
        Product prod = load(Product.class, 40L);
        Item itm = new Item(prod, 1, BigDecimal.valueOf(2.3));
        addItemToInvoice(inv, itm);       
        
        tx.commit();
    }
    
    private static <T> T load(Class<T> class_, Serializable id) {
        log.debug("load class={}, id={}", class_, id);
        return (T) getSession().load(class_, id);
    }
    
    private static void addItemToInvoice(Invoice invoice, Item item) {        
        Query q = getSession().createQuery("select max(id.item) from Item where id.invoice.id = :invoiceId");
        q.setLong("invoiceId", invoice.getId());
        int maxItem = (Integer) q.uniqueResult();
        
        item.getId().setInvoice(invoice);
        item.getId().setItem(maxItem+1);        
        getSession().persist(item);
        
        invoice.getItems().add(item);
        //Zvýšení verze.
        getSession().buildLockRequest(LockOptions.NONE).setLockMode(LockMode.OPTIMISTIC_FORCE_INCREMENT).lock(invoice);
    }
    

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static Session getSession() {
        return sessionFactory.getCurrentSession();
    }
    
}
